package com.ruoyi.goods.service.impl;

import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.goods.config.DelayedConfig2;
import com.ruoyi.goods.controller.OrderController;
import com.ruoyi.goods.domain.BmGoods;
import com.ruoyi.goods.domain.BmInordergoodslist;
import com.ruoyi.goods.domain.BmInorderlist;
import com.ruoyi.goods.mapper.SeckillMapper;
import com.ruoyi.goods.service.SeckillService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author {那蓝桉}
 * @Date: 2023/08/16/ 10:54
 * @description
 */
@Service
public class SeckillServiceImpl implements SeckillService {
    @Autowired
    private RedisService redisService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private SeckillMapper seckillMapper;
    @Autowired
    private OrderController orderController;
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 创建秒杀订单
     * @param
     */
    @Override
    @Transactional
    public String saveSeckillOrder(Map<String,Object> map, List<Map<String,Object>> good) {
        //从缓存中获取秒杀商品
//        String key = "goodsList:queryAll";
//        List<BmGoods> goods =redisService.getCacheObject(key);
//        Map<String, Object> map1 = good.get(0);
//        Integer id = (Integer) map1.get("id");

        //        分布式锁,使用RedissonClient声明一个锁
        RLock lock = redissonClient.getLock("lock");
        String uuidStr = null;
        int addHead = 0;
        int addItems = 0;
        try {
//            参数1.加锁的等待时间
//            参数2.加锁以后30秒以后释放锁
//            参数3.返回值 true加锁成功，false加锁失败
            boolean b = lock.tryLock(100, 30, TimeUnit.SECONDS);
            if (b) {
                Integer id = (Integer) map.get("specificationId");
                String key = "goods:queryById" + id;
                BmGoods goods = redisService.getCacheObject(key);
                Long stock = redisService.getCacheObject("list:" + id.toString());
//        TbSeckillGoods seckillGoods=  (TbSeckillGoods) redisTemplate.boundHashOps("seckill_goods").get(seckillGoodsId);
                if (goods == null || stock <= 0) {
                    throw new RuntimeException("商品售完");
                }
                //设置秒杀商品库存减一
                if (stock > 0) {
                    stock-=1;
                    redisService.setCacheObject("list:" + id.toString(), stock);
                    System.out.println("111111stock="+stock);
                }

//        随机生成订单编号，替换掉其中的-
                String uuid = UUID.randomUUID().toString();
                uuidStr = uuid.replace("-", "");
//                uuidStr = uuid.replaceAll("[a-zA-Z]", "");

                Integer sid = (Integer) map.get("sellerId");
                String address = (String) map.get("address");
                String deliveryFee = (String) map.get("deliveryFee");
                String mark = (String) map.get("mark");

//                bl.setCreateTime(formattedDate);
                //组装秒杀订单数据
                BmInorderlist orderlist = new BmInorderlist();
//        orderlist.setOrderCode(String.valueOf(Integer.parseInt(seckillMapper.getMaxOrderCode())+1));
                orderlist.setOrderCode(uuidStr);
                orderlist.setSellerId(Long.valueOf(sid));
                orderlist.setDeliveryFee(Double.valueOf(deliveryFee));
                orderlist.setAmount(goods.getBmSpecificationList().get(0).getPrice());
                orderlist.setWarehouseCode(goods.getWarehouseCode());
                orderlist.setOrderStep(1L);//待支付
                orderlist.setOrderState(1L);//正常订单
                orderlist.setCreateTime(new Date());
                orderlist.setAddress(address);
                orderlist.setMark(mark);

                BmInordergoodslist bmInordergoodslist = new BmInordergoodslist();
                bmInordergoodslist.setOrderCode(orderlist.getOrderCode());
                bmInordergoodslist.setGoodsId(goods.getId());
                bmInordergoodslist.setSpecificationId(Long.valueOf(id));
                bmInordergoodslist.setSpecificationName(goods.getBmSpecificationList().get(0).getSpecificationName());
                bmInordergoodslist.setGoodsName(goods.getGoodsName());
                bmInordergoodslist.setGoodsImg(goods.getBmSpecificationList().get(0).getGoodsImgUrl());
                bmInordergoodslist.setBuyNum(1L);
                bmInordergoodslist.setPrice(goods.getBmSpecificationList().get(0).getPrice());

                List<BmInordergoodslist> list = new ArrayList<>();
                list.add(bmInordergoodslist);
                orderlist.setBmInordergoodslistList(list);

                //        如果账户余额>订单所需费用 创建订单主表
                Double amount = seckillMapper.getAmount(sid);
                if (amount >= Double.parseDouble(map.get("amount").toString())){
                    //保存秒杀订单
                    addHead = seckillMapper.insertOrderList(orderlist);
                    addItems = seckillMapper.insertOrderGoodsList(bmInordergoodslist);
                    orderController.createOrder(orderlist);
                }else {
                    throw new RuntimeException("余额不足订单创建失败！");
                }

                if (addHead > 0 && addItems > 0) {
                    System.out.println("addHead:" + addHead + " items:" + addItems);
                    //放到消息队列 bl
                    rabbitTemplate.convertAndSend(DelayedConfig2.DELAYED_EXCHANGE_NAME, DelayedConfig2.DELAYED_ROUTING_KEY, uuidStr, msg -> {
                        msg.getMessageProperties().setDelay(60000);//1分钟
                        return msg;
                    });
                }
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
//            手动释放锁
            lock.unlock();
        }
        return uuidStr;
    }
}
